import webSocketConfig from '../webSocketconfig.js'

/**
 * WebSocket聊天管理器
 * 负责管理WebSocket连接、消息发送接收、用户状态管理等功能
 */
class ChatManager {
  constructor() {
    this.ws = null // WebSocket连接实例
    this.connected = false // 连接状态标识
    this.messageHandlers = new Map() // 消息处理器映射
    this.reconnectAttempts = 0 // 重连尝试次数
    this.maxReconnectAttempts = 5 // 最大重连次数
    this.reconnectDelay = 3000 // 重连延迟时间（毫秒）
    this.serverUrl = 'ws://localhost:8083/ws' // WebSocket服务器地址
    console.log('ChatManager初始化，服务器地址:', this.serverUrl)
    this.currentUserId = null // 当前用户ID
    this.unreadMessages = new Map() // 未读消息映射
    this.isAppActive = true // 应用活跃状态
    this.globalMessageHandler = null // 全局消息处理器
    this.connectionStatusListeners = new Map() // 连接状态监听器映射
    this.recentConversations = new Map() // 最近会话映射
  }

  /**
   * 连接WebSocket服务器
   * @param {string} userId - 用户ID，可选参数，如果提供则作为连接参数
   * @returns {Promise} 连接Promise
   */
  async connect(userId = null) {
    // 如果已经连接，直接返回
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      return Promise.resolve()
    }

    return new Promise((resolve, reject) => {
      try {
        // 构建WebSocket连接URL，如果提供了userId则添加为查询参数
        let wsUrl = this.serverUrl
        if (userId) {
          wsUrl += `?userId=${encodeURIComponent(userId)}`
          this.currentUserId = userId
        }
        
        console.log('连接WebSocket:', wsUrl)
        this.ws = new WebSocket(wsUrl)
        
        // WebSocket连接成功事件处理
        this.ws.onopen = () => {
           console.log('WebSocket连接已建立')
           this.connected = true
           this.reconnectAttempts = 0
           
           // 通知所有监听器连接状态变化
           this.notifyConnectionStatusChange(true)
           
           // 如果提供了用户ID，延迟调用登录以确保连接完全建立
           if (userId) {
             // 使用setTimeout确保WebSocket状态完全切换到OPEN
             setTimeout(() => {
               try {
                 this.login(userId)
               } catch (error) {
                 console.error('自动登录失败:', error)
               }
             }, 50) // 50ms延迟，确保连接状态稳定
           }
           
           resolve()
         }

        // WebSocket消息接收事件处理
        this.ws.onmessage = (event) => {
          try {
            const message = JSON.parse(event.data)
            this.handleMessage(message)
          } catch (error) {
            console.error('解析消息失败:', error)
          }
        }

        // WebSocket连接关闭事件处理
        this.ws.onclose = () => {
           console.log('WebSocket连接已关闭')
           this.connected = false
           
           // 通知所有监听器连接状态变化
           this.notifyConnectionStatusChange(false)
           
           // 尝试重新连接
           this.attemptReconnect()
         }

        // WebSocket错误事件处理
        this.ws.onerror = (error) => {
           console.error('WebSocket错误:', error)
           this.connected = false
           
           // 通知所有监听器连接状态变化
           this.notifyConnectionStatusChange(false)
           
           reject(error)
         }

      } catch (error) {
        reject(error)
      }
    })
  }

  /**
   * 断开WebSocket连接
   */
  disconnect() {
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    this.connected = false
  }

  /**
   * 尝试重新连接WebSocket
   */
  attemptReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++
      console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
      
      setTimeout(() => {
        this.connect(this.currentUserId)
      }, this.reconnectDelay)
    } else {
      console.log('重连失败，已达到最大重试次数')
    }
  }

  /**
   * 用户登录 - 支持状态检查和自动重试
   * @param {string} userId - 用户ID
   * @param {string} username - 用户名，可选，默认使用userId
   * @param {number} retryCount - 重试次数，内部使用
   */
  login(userId, username = null, retryCount = 0) {
    const maxRetries = 3 // 最大重试次数
    const retryDelay = 100 // 重试延迟（毫秒）
    
    // 检查WebSocket连接状态
    if (!this.ws) {
      throw new Error('WebSocket未初始化')
    }
    
    // 如果WebSocket仍在连接中，等待后重试
    if (this.ws.readyState === WebSocket.CONNECTING) {
      if (retryCount < maxRetries) {
        console.log(`WebSocket仍在连接中，${retryDelay}ms后重试登录 (${retryCount + 1}/${maxRetries})`)
        setTimeout(() => {
          this.login(userId, username, retryCount + 1)
        }, retryDelay)
        return
      } else {
        throw new Error('WebSocket连接超时，登录失败')
      }
    }
    
    // 检查WebSocket是否已打开
    if (this.ws.readyState !== WebSocket.OPEN) {
      throw new Error('WebSocket连接未打开，当前状态: ' + this.ws.readyState)
    }

    try {
      const message = {
        Type: 'login',
        UserId: userId,
        Username: username || userId,
        Content: '',
        Timestamp: new Date().toISOString()
      }

      this.ws.send(JSON.stringify(message))
      this.currentUserId = userId
      this.currentUsername = username || userId
      console.log('登录消息已发送:', userId)
    } catch (error) {
      console.error('发送登录消息失败:', error)
      throw error
    }
  }

  /**
   * 发送私聊消息
   * @param {string} targetUserId - 目标用户ID
   * @param {string} content - 消息内容
   * @param {string} productId - 商品ID，可选
   * @returns {Object} 消息对象，用于本地显示
   */
  sendMessage(targetUserId, content, productId = null) {
    // 检查连接状态
    if (!this.connected) {
      throw new Error('WebSocket未连接')
    }

    // 检查用户登录状态
    if (!this.currentUserId) {
      throw new Error('用户未登录')
    }

    const messageId = this.generateMessageId()
    const message = {
      Type: 'private',
      UserId: this.currentUserId,
      Username: this.currentUsername || this.currentUserId,
      Content: content,
      TargetUserId: targetUserId,
      ProductId: productId,
      MessageId: messageId,
      Timestamp: new Date().toISOString()
    }

    this.ws.send(JSON.stringify(message))

    // 返回消息对象用于本地显示
    const localMsg = {
      messageId: messageId,
      from: this.currentUserId,
      to: targetUserId,
      content: content,
      productId: productId,
      timestamp: Date.now(),
      isSent: true,
      isOwn: true
    }

    // 记录最近会话
    this.recordRecentMessage(targetUserId, localMsg)

    return localMsg
  }

  /**
   * 订阅聊天主题（兼容性方法）
   * @param {string} targetUserId - 目标用户ID
   * @param {string} productId - 商品ID，可选
   */
  subscribeToChatTopic(targetUserId, productId = null) {
    // WebSocket模式下不需要特殊订阅操作
    console.log(`订阅聊天主题: ${targetUserId}, 商品: ${productId}`)
  }

  /**
   * 注册消息监听器
   * @param {Function} handler - 消息处理函数
   * @returns {string} 监听器ID，用于后续移除
   */
  onMessage(handler) {
    const handlerId = `handler_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    this.messageHandlers.set(handlerId, handler)
    console.log('[DEBUG] 注册消息监听器:', handlerId, '当前监听器总数:', this.messageHandlers.size)
    return handlerId
  }

  /**
   * 移除消息监听器
   * @param {string} handlerId - 监听器ID
   */
  offMessage(handlerId) {
    const removed = this.messageHandlers.delete(handlerId)
    console.log('[DEBUG] 移除消息监听器:', handlerId, '移除成功:', removed, '当前监听器总数:', this.messageHandlers.size)
  }

  /**
   * 处理接收到的消息
   * @param {Object} message - 原始消息对象
   */
  handleMessage(message) {
    console.log('[DEBUG] 收到原始消息:', message)
    console.log('[DEBUG] 消息类型:', message.Type)
    console.log('[DEBUG] 消息内容:', JSON.stringify(message, null, 2))
    
    // 转换消息格式以兼容现有代码
    let formattedMessage = null

    // 处理私聊消息
    if (message.Type === 'private') {
      console.log('[DEBUG] 处理私聊消息')
      
      // 如果是响应消息（Success字段存在），处理Data中的消息
      if (message.Success !== undefined && message.Data) {
        console.log('[DEBUG] 处理响应消息中的Data:', message.Data)
        const actualMessage = message.Data
        formattedMessage = {
          messageId: actualMessage.MessageId || this.generateMessageId(),
          from: actualMessage.UserId,
          to: actualMessage.TargetUserId,
          content: actualMessage.Content,
          productId: actualMessage.ProductId,
          timestamp: new Date(actualMessage.Timestamp).getTime(),
          isSent: false,
          isOwn: actualMessage.UserId === this.currentUserId
        }
      } 
      // 如果是直接的消息（没有Success字段），直接处理
      else if (message.Success === undefined) {
        console.log('[DEBUG] 处理直接消息')
        formattedMessage = {
          messageId: message.MessageId || this.generateMessageId(),
          from: message.UserId,
          to: message.TargetUserId,
          content: message.Content,
          productId: message.ProductId,
          timestamp: new Date(message.Timestamp).getTime(),
          isSent: false,
          isOwn: message.UserId === this.currentUserId
        }
      }
      
      console.log('[DEBUG] 格式化后的消息:', formattedMessage)
      
      // 如果不是自己发送的消息，记录为未读
      if (formattedMessage && !formattedMessage.isOwn) {
        console.log('[DEBUG] 添加未读消息')
        this.addUnreadMessage(formattedMessage.from, formattedMessage)
        // 通知未读数变化
        try { uni.$emit && uni.$emit('unreadCountChanged', this.getUnreadCount()) } catch (e) {}
      }
    } else {
      console.log('[DEBUG] 非私聊消息，类型:', message.Type)
    }

    // 通知所有监听器
    if (formattedMessage) {
      console.log('[DEBUG] 处理后的消息:', formattedMessage)
      console.log('[DEBUG] 通知监听器数量:', this.messageHandlers.size)
      this.messageHandlers.forEach((handler, handlerId) => {
        try {
          console.log('[DEBUG] 调用监听器:', handlerId)
          handler(formattedMessage)
        } catch (error) {
          console.error('[DEBUG] 消息处理器错误:', error)
        }
      })

      // 调用全局消息处理器
      if (this.globalMessageHandler) {
        try {
          this.globalMessageHandler(formattedMessage)
        } catch (e) {
          console.error('全局消息处理器错误:', e)
        }
      }

      // 广播新消息事件，供消息列表页刷新
      try { uni.$emit && uni.$emit('newMessage', { message: formattedMessage }) } catch (e) {}

      // 记录最近会话
      const otherUserId = formattedMessage.isOwn ? formattedMessage.to : formattedMessage.from
      this.recordRecentMessage(otherUserId, formattedMessage)
    } else {
      console.log('[DEBUG] 没有格式化的消息，不通知监听器')
    }
  }

  /**
   * 添加未读消息
   * @param {string} fromUserId - 发送者用户ID
   * @param {Object} message - 消息对象
   */
  addUnreadMessage(fromUserId, message) {
    if (!this.unreadMessages.has(fromUserId)) {
      this.unreadMessages.set(fromUserId, [])
    }
    this.unreadMessages.get(fromUserId).push(message)
  }

  /**
   * 获取未读消息数量
   * @param {string} userId - 用户ID，可选，如果不提供则返回总数
   * @returns {number} 未读消息数量
   */
  getUnreadCount(userId = null) {
    if (userId) {
      const messages = this.unreadMessages.get(userId)
      return messages ? messages.length : 0
    }
    
    // 返回总未读消息数量
    let total = 0
    this.unreadMessages.forEach(messages => {
      total += messages.length
    })
    return total
  }

  /**
   * 清除指定用户的未读消息
   * @param {string} userId - 用户ID
   */
  clearUnreadMessages(userId) {
    this.unreadMessages.delete(userId)
    try { uni.$emit && uni.$emit('unreadCountChanged', this.getUnreadCount()) } catch (e) {}
  }

  /**
   * 获取所有有未读消息的用户列表
   * @returns {Array} 用户ID数组
   */
  getUnreadMessageUsers() {
    return Array.from(this.unreadMessages.keys())
  }

  /**
   * 设置应用活跃状态
   * @param {boolean} isActive - 是否活跃
   */
  setAppActive(isActive) {
    this.isAppActive = isActive
  }

  /**
   * 注册全局消息处理器
   * @param {Function} handler - 全局消息处理函数
   */
  setGlobalMessageHandler(handler) {
    this.globalMessageHandler = handler
  }

  /**
   * 移除全局消息处理器
   */
  removeGlobalMessageHandler() {
    this.globalMessageHandler = null
  }

  /**
   * 注册连接状态变化监听器
   * @param {Function} handler - 状态变化处理函数
   * @returns {string} 监听器ID
   */
  onConnectionStatusChange(handler) {
    if (!this.connectionStatusListeners) {
      this.connectionStatusListeners = new Map()
    }
    const listenerId = this.generateMessageId()
    this.connectionStatusListeners.set(listenerId, handler)
    return listenerId
  }

  /**
   * 移除连接状态监听器
   * @param {string} listenerId - 监听器ID
   */
  removeConnectionStatusListener(listenerId) {
    if (this.connectionStatusListeners) {
      this.connectionStatusListeners.delete(listenerId)
    }
  }

  /**
   * 通知所有监听器连接状态变化
   * @param {boolean} status - 连接状态
   */
  notifyConnectionStatusChange(status) {
    if (this.connectionStatusListeners) {
      this.connectionStatusListeners.forEach(handler => {
        try {
          handler(status)
        } catch (error) {
          console.error('连接状态监听器执行错误:', error)
        }
      })
    }
  }

  /**
   * 获取当前连接状态
   * @returns {boolean} 连接状态
   */
  getConnectionStatus() {
    return this.connected
  }

  /**
   * 检查是否已连接（向后兼容方法）
   * @returns {boolean} 连接状态
   */
  isConnected() {
    return this.connected
  }

  /**
   * 生成唯一消息ID
   * @returns {string} 消息ID
   */
  generateMessageId() {
    return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 设置WebSocket服务器地址
   * @param {string} url - 服务器地址
   */
  setServerUrl(url) {
    this.serverUrl = url
  }

  /**
   * 记录最近会话
   * @param {string} otherUserId - 对方用户ID
   * @param {Object} message - 消息对象
   */
  recordRecentMessage(otherUserId, message) {
    const unread = this.getUnreadCount(otherUserId)
    this.recentConversations.set(otherUserId, { latest: message, unread })
  }

  /**
   * 获取最近会话列表，按最新时间倒序
   * @returns {Array<{userId:string, latest:Object, unread:number}>}
   */
  getRecentConversations() {
    return Array.from(this.recentConversations.entries())
      .map(([userId, info]) => ({ userId, latest: info.latest, unread: info.unread }))
      .sort((a, b) => (b.latest.timestamp - a.latest.timestamp))
  }
}

// 创建单例实例
const chatManager = new ChatManager()

export default chatManager